package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.base.model.RestResponse;
import com.xuecheng.content.mapper.TeachPlanMapper;
import com.xuecheng.content.mapper.TeachplanMediaMapper;
import com.xuecheng.content.service.TeachPlanService;
import com.xuecheng.domain.dto.BindTeachplanMediaDto;
import com.xuecheng.domain.dto.SaveTeachplanDto;
import com.xuecheng.domain.dto.TeachPlanDto;
import com.xuecheng.domain.po.Teachplan;
import com.xuecheng.domain.po.TeachplanMedia;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @author Administrator
 */
@Slf4j
@Service
public class TeachPlanServiceImpl implements TeachPlanService {
    @Resource
    private TeachPlanMapper teachplanMapper;

    @Resource
    private TeachplanMediaMapper teachplanMediaMapper;
    @Override
    public List<TeachPlanDto> findTeachplanTree(Long courseId) {
        return teachplanMapper.selectTreeNodes(courseId);
    }

    @Override
    @Transactional
    public void saveTeachplan(Teachplan saveTeachplanDto) {
        Long teachPlanId = saveTeachplanDto.getId();
        if (teachPlanId == null) {
            //新增
            Teachplan teachplan = new Teachplan();
            //确定排序字段，找到它的同级别节点个数然后+1
            Long parentId = saveTeachplanDto.getParentid();
            Long courseId = saveTeachplanDto.getCourseId();
            LambdaQueryWrapper<Teachplan> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(Teachplan::getCourseId, courseId);
            lambdaQueryWrapper.eq(Teachplan::getParentid, parentId);
            int count = Math.toIntExact(teachplanMapper.selectCount(lambdaQueryWrapper));
            teachplan.setOrderby(count+1);
            BeanUtils.copyProperties(saveTeachplanDto, teachplan);
            int i = teachplanMapper.insert(teachplan);
            if (i <= 0) {
                XueChengPlusException.cast("新增失败");
            }
        } else {
            // 修改
            Teachplan teachplan = teachplanMapper.selectById(teachPlanId);
            if (teachplan == null) {
                XueChengPlusException.cast("课程计划不存在，无法修改");
            }
            BeanUtils.copyProperties(saveTeachplanDto, teachplan);
            int rows = teachplanMapper.updateById(teachplan);
            if (rows <= 0) {
                XueChengPlusException.cast("修改失败");
            }
        }

    }

    @Override
    @Transactional
    public void deleteTeachplan(Long teachplanId) {
        if (teachplanId == null) {
            XueChengPlusException.cast("课程计划id为空");
        }
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if (teachplan == null) {
            XueChengPlusException.cast("课程计划不存在，无法删除");
        }
        //判断当前课程计划是章还是节
        Integer grade = teachplan.getGrade();
        if(grade == 1){
            //查询当前课程下是否有小节
            LambdaQueryWrapper<Teachplan> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            // select * from teachplan where parentid = {当前章计划id}
            lambdaQueryWrapper.eq(Teachplan::getParentid, teachplanId);
            Long count = teachplanMapper.selectCount(lambdaQueryWrapper);
            if (count > 0) {
                XueChengPlusException.cast("课程计划信息还有子级信息，无法操作");
            }
        } else {
            //如果是节，直接删除
            // 课程计划下无小节，直接删除该课程计划和对应的媒资信息
            teachplanMapper.deleteById(teachplanId);
            // 条件构造器
            LambdaQueryWrapper<TeachplanMedia> mediaLambdaQueryWrapper = new LambdaQueryWrapper<>();
            // 删除媒资信息中对应teachplanId的数据
            mediaLambdaQueryWrapper.eq(TeachplanMedia::getTeachplanId, teachplanId);
            teachplanMediaMapper.delete(mediaLambdaQueryWrapper);
        }
    }

    @Override
    @Transactional
    public void orderByTeachplan(String moveType, Long teachplanId) {
        //先查询出该课程计划id下得所有章节与小节节点信息
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        //根据grade判断是章移动还是节移动
        if (teachplan == null) {
            XueChengPlusException.cast("课程计划不存在");
        }

        Integer grade = teachplan.getGrade();
        //章节移动比较同一courseId下得orderBy字段 , 节移动比较同一parentid下得orderBy字段
        Long courseId = teachplan.getCourseId();
        Long parentId = teachplan.getParentid();
        Integer orderby = teachplan.getOrderby();
        //先判断是向上移动还是向下移动
        if("moveup".equals(moveType)){
            if(grade == 1){
                // 章节上移，找到上一个章节的orderby，然后与其交换orderby
                // SELECT * FROM teachplan WHERE courseId = 117 AND grade = 1  AND orderby < 1 ORDER BY orderby DESC LIMIT 1
                LambdaQueryWrapper<Teachplan> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(Teachplan::getCourseId, courseId);
                lambdaQueryWrapper.eq(Teachplan::getGrade, grade);
                lambdaQueryWrapper.lt(Teachplan::getOrderby, orderby);
                lambdaQueryWrapper.orderByDesc(Teachplan::getOrderby);
                lambdaQueryWrapper.last("LIMIT 1");
                Teachplan selectOne = teachplanMapper.selectOne(lambdaQueryWrapper);
                exchangeOrderBy(teachplan, selectOne);
            }else if (grade == 2){
                // 小节上移
                // SELECT * FROM teachplan WHERE parentId = 268 AND orderby < 5 ORDER BY orderby DESC LIMIT 1
                LambdaQueryWrapper<Teachplan> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(Teachplan::getParentid, parentId);
                lambdaQueryWrapper.eq(Teachplan::getGrade, grade);
                lambdaQueryWrapper.lt(Teachplan::getOrderby, orderby);
                lambdaQueryWrapper.orderByDesc(Teachplan::getOrderby);
                lambdaQueryWrapper.last("LIMIT 1");
                Teachplan selectOne = teachplanMapper.selectOne(lambdaQueryWrapper);
                exchangeOrderBy(teachplan, selectOne);
        }
        }else if("movedown".equals(moveType)){
            if (grade == 1) {
                // 章节下移
                // SELECT * FROM teachplan WHERE courseId = 117 AND grade = 1 AND orderby > 1 ORDER BY orderby ASC LIMIT 1
                LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Teachplan::getCourseId, courseId)
                        .eq(Teachplan::getGrade, grade)
                        .gt(Teachplan::getOrderby, orderby)
                        .orderByAsc(Teachplan::getOrderby)
                        .last("LIMIT 1");
                Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
                exchangeOrderBy(teachplan, tmp);
            } else if (grade == 2) {
                // 小节下移
                // SELECT * FROM teachplan WHERE parentId = 268 AND orderby > 1 ORDER BY orderby ASC LIMIT 1
                LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Teachplan::getParentid, parentId)
                        .gt(Teachplan::getOrderby, orderby)
                        .orderByAsc(Teachplan::getOrderby)
                        .last("LIMIT 1");
                Teachplan tmp = teachplanMapper.selectOne(queryWrapper);
                exchangeOrderBy(teachplan, tmp);
            }
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void associationMedia(BindTeachplanMediaDto bindTeachplanMediaDto) {
        Long teachplanId = bindTeachplanMediaDto.getTeachplanId();
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if (teachplan == null) {
            XueChengPlusException.cast("课程计划不存在");
        }
        //先删除原有记录，根据课程计划的id删除绑定的媒资信息
        LambdaQueryWrapper<TeachplanMedia> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TeachplanMedia::getTeachplanId, bindTeachplanMediaDto.getTeachplanId());
        int i = teachplanMediaMapper.delete(queryWrapper);
        //添加原有记录
        TeachplanMedia teachplanMedia = new TeachplanMedia();
        BeanUtils.copyProperties(bindTeachplanMediaDto, teachplanMedia);
        teachplanMedia.setMediaFilename(bindTeachplanMediaDto.getFileName());
        teachplanMedia.setCourseId(teachplan.getCourseId());
        teachplanMedia.setCreateDate(LocalDateTime.now());
        int insert = teachplanMediaMapper.insert(teachplanMedia);
        if (insert >= 0){
            RestResponse.success(true);
        }
    }


    /**
     * 交换两个Teachplan的orderby
     * @param teachplan
     * @param tmp
     */
    private void exchangeOrderBy(Teachplan teachplan, Teachplan tmp) {
        if (tmp == null)
            XueChengPlusException.cast("已经到头啦，不能再移啦");
        else {
            // 交换orderby，更新
            Integer teachPlanOrderBy = teachplan.getOrderby();
            Integer lastOrderBy = tmp.getOrderby();
            int temp = lastOrderBy;
            lastOrderBy = teachPlanOrderBy;
            teachPlanOrderBy = temp;
           teachplan.setOrderby(lastOrderBy);
           tmp.setOrderby(teachPlanOrderBy);
           teachplanMapper.updateById(teachplan);
           teachplanMapper.updateById(tmp);
        }
    }
}
